<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>

<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.33">

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">


<title>7&nbsp; Project 2 - Building a HTTP Server from scratch – Introduction to Zig</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
  width: 0.8em;
  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
  vertical-align: middle;
}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
/* CSS for citations */
div.csl-bib-body { }
div.csl-entry {
  clear: both;
  margin-bottom: 0em;
}
.hanging-indent div.csl-entry {
  margin-left:2em;
  text-indent:-2em;
}
div.csl-left-margin {
  min-width:2em;
  float:left;
}
div.csl-right-inline {
  margin-left:2em;
  padding-left:1em;
}
div.csl-indent {
  margin-left: 2em;
}</style>


<script src="../site_libs/quarto-nav/quarto-nav.js"></script>
<script src="../site_libs/quarto-nav/headroom.min.js"></script>
<script src="../site_libs/clipboard/clipboard.min.js"></script>
<script src="../site_libs/quarto-search/autocomplete.umd.js"></script>
<script src="../site_libs/quarto-search/fuse.min.js"></script>
<script src="../site_libs/quarto-search/quarto-search.js"></script>
<meta name="quarto:offset" content="../">
<link href="../Chapters/03-unittests.html" rel="next">
<link href="../Chapters/05-pointers.html" rel="prev">
<script src="../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../site_libs/quarto-html/popper.min.js"></script>
<script src="../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../site_libs/quarto-html/anchor.min.js"></script>
<link href="../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-59898bd1c6b9d2bb783127feaa000c76.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-dark-d329e753491efaeac79c98c4b193a686.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../site_libs/quarto-html/quarto-syntax-highlighting-59898bd1c6b9d2bb783127feaa000c76.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
<script src="../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../site_libs/bootstrap/bootstrap-5a7d69291c2a8c67bc3a157f4354e263.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../site_libs/bootstrap/bootstrap-dark-a459d9a911ec262923466a12d18bc01e.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../site_libs/bootstrap/bootstrap-5a7d69291c2a8c67bc3a157f4354e263.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
  "location": "sidebar",
  "copy-button": false,
  "collapse-after": 3,
  "panel-placement": "start",
  "type": "textbox",
  "limit": 50,
  "keyboard-shortcut": [
    "f",
    "/",
    "s"
  ],
  "show-item-context": false,
  "language": {
    "search-no-results-text": "No results",
    "search-matching-documents-text": "matching documents",
    "search-copy-link-title": "Copy link to search",
    "search-hide-matches-text": "Hide additional matches",
    "search-more-match-text": "more match in this document",
    "search-more-matches-text": "more matches in this document",
    "search-clear-button-title": "Clear",
    "search-text-placeholder": "",
    "search-detached-cancel-button-title": "Cancel",
    "search-submit-button-title": "Submit",
    "search-label": "Search"
  }
}</script>
<script async="" src="https://www.googletagmanager.com/gtag/js?id=G-6CHJXK4CEV"></script>

<script type="text/javascript">

window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-6CHJXK4CEV', { 'anonymize_ip': true});
</script>


</head>

<body class="nav-sidebar floating quarto-light"><script id="quarto-html-before-body" type="application/javascript">
    const toggleBodyColorMode = (bsSheetEl) => {
      const mode = bsSheetEl.getAttribute("data-mode");
      const bodyEl = window.document.querySelector("body");
      if (mode === "dark") {
        bodyEl.classList.add("quarto-dark");
        bodyEl.classList.remove("quarto-light");
      } else {
        bodyEl.classList.add("quarto-light");
        bodyEl.classList.remove("quarto-dark");
      }
    }
    const toggleBodyColorPrimary = () => {
      const bsSheetEl = window.document.querySelector("link#quarto-bootstrap:not([rel=disabled-stylesheet])");
      if (bsSheetEl) {
        toggleBodyColorMode(bsSheetEl);
      }
    }
    const setColorSchemeToggle = (alternate) => {
      const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
      for (let i=0; i < toggles.length; i++) {
        const toggle = toggles[i];
        if (toggle) {
          if (alternate) {
            toggle.classList.add("alternate");
          } else {
            toggle.classList.remove("alternate");
          }
        }
      }
    };
    const toggleColorMode = (alternate) => {
      // Switch the stylesheets
      const primaryStylesheets = window.document.querySelectorAll('link.quarto-color-scheme:not(.quarto-color-alternate)');
      const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
      manageTransitions('#quarto-margin-sidebar .nav-link', false);
      if (alternate) {
        // note: dark is layered on light, we don't disable primary!
        enableStylesheet(alternateStylesheets);
        for (const sheetNode of alternateStylesheets) {
          if (sheetNode.id === "quarto-bootstrap") {
            toggleBodyColorMode(sheetNode);
          }
        }
      } else {
        disableStylesheet(alternateStylesheets);
        enableStylesheet(primaryStylesheets)
        toggleBodyColorPrimary();
      }
      manageTransitions('#quarto-margin-sidebar .nav-link', true);
      // Switch the toggles
      setColorSchemeToggle(alternate)
      // Hack to workaround the fact that safari doesn't
      // properly recolor the scrollbar when toggling (#1455)
      if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
        manageTransitions("body", false);
        window.scrollTo(0, 1);
        setTimeout(() => {
          window.scrollTo(0, 0);
          manageTransitions("body", true);
        }, 40);
      }
    }
    const disableStylesheet = (stylesheets) => {
      for (let i=0; i < stylesheets.length; i++) {
        const stylesheet = stylesheets[i];
        stylesheet.rel = 'disabled-stylesheet';
      }
    }
    const enableStylesheet = (stylesheets) => {
      for (let i=0; i < stylesheets.length; i++) {
        const stylesheet = stylesheets[i];
        if(stylesheet.rel !== 'stylesheet') { // for Chrome, which will still FOUC without this check
          stylesheet.rel = 'stylesheet';
        }
      }
    }
    const manageTransitions = (selector, allowTransitions) => {
      const els = window.document.querySelectorAll(selector);
      for (let i=0; i < els.length; i++) {
        const el = els[i];
        if (allowTransitions) {
          el.classList.remove('notransition');
        } else {
          el.classList.add('notransition');
        }
      }
    }
    const isFileUrl = () => {
      return window.location.protocol === 'file:';
    }
    const hasAlternateSentinel = () => {
      let styleSentinel = getColorSchemeSentinel();
      if (styleSentinel !== null) {
        return styleSentinel === "alternate";
      } else {
        return false;
      }
    }
    const setStyleSentinel = (alternate) => {
      const value = alternate ? "alternate" : "default";
      if (!isFileUrl()) {
        window.localStorage.setItem("quarto-color-scheme", value);
      } else {
        localAlternateSentinel = value;
      }
    }
    const getColorSchemeSentinel = () => {
      if (!isFileUrl()) {
        const storageValue = window.localStorage.getItem("quarto-color-scheme");
        return storageValue != null ? storageValue : localAlternateSentinel;
      } else {
        return localAlternateSentinel;
      }
    }
    const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
      const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
      const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
      let newTheme = '';
      if(authorPrefersDark) {
        newTheme = isAlternate ? baseTheme : alternateTheme;
      } else {
        newTheme = isAlternate ? alternateTheme : baseTheme;
      }
      const changeGiscusTheme = () => {
        // From: https://github.com/giscus/giscus/issues/336
        const sendMessage = (message) => {
          const iframe = document.querySelector('iframe.giscus-frame');
          if (!iframe) return;
          iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
        }
        sendMessage({
          setConfig: {
            theme: newTheme
          }
        });
      }
      const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
      if (isGiscussLoaded) {
        changeGiscusTheme();
      }
    };
    const authorPrefersDark = false;
    const darkModeDefault = authorPrefersDark;
      document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
      document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
    let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
    // Dark / light mode switch
    window.quartoToggleColorScheme = () => {
      // Read the current dark / light value
      let toAlternate = !hasAlternateSentinel();
      toggleColorMode(toAlternate);
      setStyleSentinel(toAlternate);
      toggleGiscusIfUsed(toAlternate, darkModeDefault);
      window.dispatchEvent(new Event('resize'));
    };
    // Switch to dark mode if need be
    if (hasAlternateSentinel()) {
      toggleColorMode(true);
    } else {
      toggleColorMode(false);
    }
  </script>

<div id="quarto-search-results"></div>
  <header id="quarto-header" class="headroom fixed-top">
  <nav class="quarto-secondary-nav">
    <div class="container-fluid d-flex">
      <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" role="button" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
        <i class="bi bi-layout-text-sidebar-reverse"></i>
      </button>
        <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="../Chapters/04-http-server.html"><span class="chapter-number">7</span>&nbsp; <span class="chapter-title">Project 2 - Building a HTTP Server from scratch</span></a></li></ol></nav>
        <a class="flex-grow-1" role="navigation" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">      
        </a>
      <button type="button" class="btn quarto-search-button" aria-label="Search" onclick="window.quartoOpenSearch();">
        <i class="bi bi-search"></i>
      </button>
    </div>
  </nav>
</header>
<!-- content -->
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article">
<!-- sidebar -->
  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation floating overflow-auto">
    <div class="pt-lg-2 mt-2 text-left sidebar-header">
    <div class="sidebar-title mb-0 py-0">
      <a href="../">Introduction to Zig</a> 
        <div class="sidebar-tools-main">
  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
</div>
    </div>
      </div>
        <div class="mt-2 flex-shrink-0 align-items-center">
        <div class="sidebar-search">
        <div id="quarto-search" class="" title="Search"></div>
        </div>
        </div>
    <div class="sidebar-menu-container"> 
    <ul class="list-unstyled mt-1">
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../index.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">Welcome</span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-zig-weird.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">1</span>&nbsp; <span class="chapter-title">Introducing Zig</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/03-structs.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">2</span>&nbsp; <span class="chapter-title">Control flow, structs, modules and types</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-memory.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">3</span>&nbsp; <span class="chapter-title">Memory and Allocators</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/01-base64.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">4</span>&nbsp; <span class="chapter-title">Project 1 - Building a base64 encoder/decoder</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/02-debugging.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">5</span>&nbsp; <span class="chapter-title">Debugging Zig applications</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/05-pointers.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">6</span>&nbsp; <span class="chapter-title">Pointers and Optionals</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/04-http-server.html" class="sidebar-item-text sidebar-link active">
 <span class="menu-text"><span class="chapter-number">7</span>&nbsp; <span class="chapter-title">Project 2 - Building a HTTP Server from scratch</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/03-unittests.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">8</span>&nbsp; <span class="chapter-title">Unit tests</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/07-build-system.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">9</span>&nbsp; <span class="chapter-title">Build System</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/09-error-handling.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">10</span>&nbsp; <span class="chapter-title">Error handling and unions</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/09-data-structures.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">11</span>&nbsp; <span class="chapter-title">Data Structures</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/10-stack-project.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">12</span>&nbsp; <span class="chapter-title">Project 3 - Building a stack data structure</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/12-file-op.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">13</span>&nbsp; <span class="chapter-title">Filesystem and Input/Output (IO)</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/14-zig-c-interop.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">14</span>&nbsp; <span class="chapter-title">Zig interoperability with C</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/13-image-filter.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">15</span>&nbsp; <span class="chapter-title">Project 4 - Developing an image filter</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/14-threads.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">16</span>&nbsp; <span class="chapter-title">Introducing threads and parallelism in Zig</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/15-vectors.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text"><span class="chapter-number">17</span>&nbsp; <span class="chapter-title">Introducing Vectors and SIMD</span></span></a>
  </div>
</li>
        <li class="sidebar-item">
  <div class="sidebar-item-container"> 
  <a href="../Chapters/references.html" class="sidebar-item-text sidebar-link">
 <span class="menu-text">References</span></a>
  </div>
</li>
    </ul>
    </div>
</nav>
<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
<!-- margin-sidebar -->
    <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
        <nav id="TOC" role="doc-toc" class="toc-active">
    <h2 id="toc-title">Table of contents</h2>
   
  <ul>
  <li><a href="#what-is-a-http-server" id="toc-what-is-a-http-server" class="nav-link active" data-scroll-target="#what-is-a-http-server"><span class="header-section-number">7.1</span> What is a HTTP Server?</a></li>
  <li><a href="#sec-how-http-works" id="toc-sec-how-http-works" class="nav-link" data-scroll-target="#sec-how-http-works"><span class="header-section-number">7.2</span> How a HTTP Server works?</a></li>
  <li><a href="#sec-http-how-impl" id="toc-sec-http-how-impl" class="nav-link" data-scroll-target="#sec-http-how-impl"><span class="header-section-number">7.3</span> How a HTTP server is normally implemented?</a></li>
  <li><a href="#implementing-the-server---part-1" id="toc-implementing-the-server---part-1" class="nav-link" data-scroll-target="#implementing-the-server---part-1"><span class="header-section-number">7.4</span> Implementing the server - Part 1</a>
  <ul class="collapse">
  <li><a href="#sec-create-socket" id="toc-sec-create-socket" class="nav-link" data-scroll-target="#sec-create-socket"><span class="header-section-number">7.4.1</span> Creating the server object</a></li>
  <li><a href="#listening-and-receiving-connections" id="toc-listening-and-receiving-connections" class="nav-link" data-scroll-target="#listening-and-receiving-connections"><span class="header-section-number">7.4.2</span> Listening and receiving connections</a></li>
  <li><a href="#sec-read-http-message" id="toc-sec-read-http-message" class="nav-link" data-scroll-target="#sec-read-http-message"><span class="header-section-number">7.4.3</span> Reading the message from the client</a></li>
  </ul></li>
  <li><a href="#looking-at-the-current-state-of-the-program" id="toc-looking-at-the-current-state-of-the-program" class="nav-link" data-scroll-target="#looking-at-the-current-state-of-the-program"><span class="header-section-number">7.5</span> Looking at the current state of the program</a></li>
  <li><a href="#sec-enum" id="toc-sec-enum" class="nav-link" data-scroll-target="#sec-enum"><span class="header-section-number">7.6</span> Learning about Enums in Zig</a></li>
  <li><a href="#implementing-the-server---part-2" id="toc-implementing-the-server---part-2" class="nav-link" data-scroll-target="#implementing-the-server---part-2"><span class="header-section-number">7.7</span> Implementing the server - Part 2</a>
  <ul class="collapse">
  <li><a href="#the-top-level-header" id="toc-the-top-level-header" class="nav-link" data-scroll-target="#the-top-level-header"><span class="header-section-number">7.7.1</span> The top-level header</a></li>
  <li><a href="#the-list-of-http-headers" id="toc-the-list-of-http-headers" class="nav-link" data-scroll-target="#the-list-of-http-headers"><span class="header-section-number">7.7.2</span> The list of HTTP headers</a></li>
  <li><a href="#the-body" id="toc-the-body" class="nav-link" data-scroll-target="#the-body"><span class="header-section-number">7.7.3</span> The body</a></li>
  <li><a href="#creating-the-http-method-enum" id="toc-creating-the-http-method-enum" class="nav-link" data-scroll-target="#creating-the-http-method-enum"><span class="header-section-number">7.7.4</span> Creating the HTTP Method enum</a></li>
  <li><a href="#writing-the-parse-request-function" id="toc-writing-the-parse-request-function" class="nav-link" data-scroll-target="#writing-the-parse-request-function"><span class="header-section-number">7.7.5</span> Writing the parse request function</a></li>
  <li><a href="#using-the-parse-request-function" id="toc-using-the-parse-request-function" class="nav-link" data-scroll-target="#using-the-parse-request-function"><span class="header-section-number">7.7.6</span> Using the parse request function</a></li>
  <li><a href="#sending-the-http-response-to-the-client" id="toc-sending-the-http-response-to-the-client" class="nav-link" data-scroll-target="#sending-the-http-response-to-the-client"><span class="header-section-number">7.7.7</span> Sending the HTTP Response to the client</a></li>
  </ul></li>
  <li><a href="#the-end-result" id="toc-the-end-result" class="nav-link" data-scroll-target="#the-end-result"><span class="header-section-number">7.8</span> The end result</a></li>
  </ul>
</nav>
    </div>
<!-- main -->
<main class="content" id="quarto-document-content">


<header id="title-block-header" class="quarto-title-block default">
<div class="quarto-title">
<h1 class="title"><span class="chapter-number">7</span>&nbsp; <span class="chapter-title">Project 2 - Building a HTTP Server from scratch</span></h1>
</div>



<div class="quarto-title-meta">

    
  
    
  </div>
  


</header>


<p>In this chapter, I want to implement a new small project with you. This time, we are going to implement a basic HTTP Server from scratch.</p>
<p>The Zig Standard Library already have a HTTP Server implemented, which is available at <code>std.http.Server</code>. But again, our objective here in this chapter, is to implement it <strong>from scratch</strong>. So we can’t use this server object available from the Zig Standard Library.</p>
<section id="what-is-a-http-server" class="level2" data-number="7.1">
<h2 data-number="7.1" class="anchored" data-anchor-id="what-is-a-http-server"><span class="header-section-number">7.1</span> What is a HTTP Server?</h2>
<p>First of all, what is a HTTP Server? A HTTP server, as any other type of server, is essentially a program that runs indefinitely, on an infinite loop, waiting for incoming connections from clients. Once the server receives an incoming connection, it will accept this connection, and it will send messages back-and-forth to the client through this connection.</p>
<p>But the messages that are transmitted inside this connection are in a specific format. They are HTTP messages (i.e., messages that use the HTTP Protocol specification). The HTTP Protocol is the backbone of the modern web. The world wide web as we know it today, would not exist without the HTTP Protocol.</p>
<p>So, Web servers (which is just a fancy name to HTTP Servers) are servers that exchange HTTP messages with clients. And these HTTP servers and the HTTP Protocol specification are essential to the operation of the world wide web today.</p>
<p>That is the whole picture of the process. Again, we have two subjects involved here, a server (which is a program that is running indefinitely, waiting to receive incoming connections), and a client (which is someone that wants to connect to the server, and exchange HTTP messages with it).</p>
<p>You may find the material about the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview">HTTP Protocol available at the Mozilla MDN Docs</a><a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> , a great resource for you to also look at. It gives you a great overview on how HTTP works, and what role the server plays in this matter.</p>
</section>
<section id="sec-how-http-works" class="level2" data-number="7.2">
<h2 data-number="7.2" class="anchored" data-anchor-id="sec-how-http-works"><span class="header-section-number">7.2</span> How a HTTP Server works?</h2>
<p>Imagine a HTTP Server as if it were the receptionist of a large hotel. In a hotel, you have a reception, and inside that reception there is a receptionist waiting for customers to arrive. A HTTP Server is essentially a receptionist that is indefinitely waiting for new customers (or, in the context of HTTP, new clients) to arrive in the hotel.</p>
<p>When a customer arrives at the hotel, that customer starts a conversation with the receptionist. He tells the receptionist how many days he wants to stay at the hotel. Then, the receptionist search for an available apartment. If there is an available apartment at the moment, the customer pays the hotel fees, then, he gets the keys to the apartment, and then, he goes to the apartment to rest.</p>
<p>After this entire process of dealing with the customer (searching for available apartments, receiving payment, handing over the keys), the receptionist goes back to what he was doing earlier, which is to wait. Wait for new customers to arrive.</p>
<p>That is, in a nutshell, what a HTTP Server do. It waits for clients to connect to the server. When a client attempts to connect to the server, the server accepts this connection, and it starts to exchange messages with the client through this connection. The first message that happens inside this connection is always a message from the client to the server. This message is called the <em>HTTP Request</em>.</p>
<p>This HTTP Request is a HTTP message that contains what the client wants from the server. It is literally a request. The client that connected to the server is asking this server to do something for him.</p>
<p>There are different “types of request” that a client can send to a HTTP Server. But the most basic type of request, is when a client ask to the HTTP Server to serve (i.e., to send) some specific web page (which is a HTML file) to him. When you type <code>google.com</code> in your web browser, you are essentially sending a HTTP Request to Google’s HTTP servers. This request is asking these servers to send the Google webpage to you.</p>
<p>Nonetheless, when the server receives this first message, the <em>HTTP Request</em>, it analyzes this request, to understand: who the client is? What he wants the server to do? This client has provided all the necessary information to perform the action that he asked? Etc.</p>
<p>Once the server understands what the client wants, he simply perform the action that was requested, and, to finish the whole process, the server sends back a HTTP message to the client, informing if the action performed was successful or not, and, at last, the server ends (or closes) the connection with the client.</p>
<p>This last HTTP message sent from the server to the client, is called the <em>HTTP Response</em>. Because the server is responding to the action that was requested by the client. The main objective of this response message is let the client know if the action requested was successful or not, before the server closes the connection.</p>
</section>
<section id="sec-http-how-impl" class="level2" data-number="7.3">
<h2 data-number="7.3" class="anchored" data-anchor-id="sec-http-how-impl"><span class="header-section-number">7.3</span> How a HTTP server is normally implemented?</h2>
<p>Let’s use the C language as an example. There are many materials teaching how to write a simple HTTP server in C code, like <span class="citation" data-cites="jeffrey_http">Yu (<a href="references.html#ref-jeffrey_http" role="doc-biblioref">2023</a>)</span>, or <span class="citation" data-cites="nipun_http">Weerasiri (<a href="references.html#ref-nipun_http" role="doc-biblioref">2023</a>)</span>, or <span class="citation" data-cites="eric_http">Meehan (<a href="references.html#ref-eric_http" role="doc-biblioref">2021</a>)</span>. Having this in mind, I will not show C code examples here, because you can find them on the internet. But I will describe the theory behind the necessary steps to create such HTTP server in C.</p>
<p>In essence, we normally implement a HTTP server in C by using a TCP socket, which involves the following steps:</p>
<ol type="1">
<li>Create a TCP socket object.</li>
<li>Bind a name (or more specifically, an address) to this socket object.</li>
<li>Make this socket object to start listening and waiting for incoming connections.</li>
<li>When a connection arrive, we accept this connection, and we exchange the HTTP messages (HTTP Request and HTTP Response).</li>
<li>Then, we simply close this connection.</li>
</ol>
<p>A socket object is essentially a channel of communication. You are creating a channel where people can send messages through. When you create a socket object, this object is not binded to any particular address. This means that with this object you have a representation of a channel of communication in your hands. But this channel is not currently available, or, it is not currently accessible, because it does not have a known address where you can find it.</p>
<p>That is what the “bind” operation do. It binds a name (or more specifically, an address) to this socket object, or, this channel of communication, so that it becomes available, or, accessible through this address. While the “listen” operation makes the socket object to listen for incoming connections in this address. In other words, the “listen” operation makes the socket wait for incoming connections.</p>
<p>Now, when a client actually attempts to connect to the server through the socket address that we have specified, in order to establish this connection with the client, the socket object needs to accept this incoming connection. Thus, when we accept an incoming connection, the client and the server become connected to each other, and they can start reading or writing messages into this established connection.</p>
<p>After we receive the HTTP Request from the client, analyze it, and send the HTTP Response to the client, we can then close the connection, and end this communication.</p>
</section>
<section id="implementing-the-server---part-1" class="level2" data-number="7.4">
<h2 data-number="7.4" class="anchored" data-anchor-id="implementing-the-server---part-1"><span class="header-section-number">7.4</span> Implementing the server - Part 1</h2>
<section id="sec-create-socket" class="level3" data-number="7.4.1">
<h3 data-number="7.4.1" class="anchored" data-anchor-id="sec-create-socket"><span class="header-section-number">7.4.1</span> Creating the server object</h3>
<p>Let’s begin by writing the code responsible for listening and accepting incoming connections to our server. Just to make things shorter, I will write this code inside a separate Zig module, named <code>server.zig</code>.</p>
<p>Now, we essentially need to create a TCP socket object in our code. On previous versions of this book, we’ve decided to create such TCP socket through the the <code>std.posix.socket()</code> function, from the Zig Standard Library. But, with the introduction of the new IO interface in Zig 0.16, this function fit’s weird on the new <code>std.Io.net.Stream</code> API.</p>
<p>Because of that, I will take a different route this time. In summary, we are going to create a TCP socket through the <a href="https://ziglang.org/documentation/master/std/#std.Io.net.IpAddress.listen"><code>listen()</code> method from <code>std.Io.net.IpAddress</code></a><a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>. Then, with this TCP socket represented by the <code>std.Io.net.Server</code> type, we use the <code>accept()</code> method to establish the connection between our server and the client. Through this “connection object” that we get from <code>accept()</code> we get access to a stream, from which we can exchange messages between the server and the client.</p>
<p>As I mentioned earlier in <a href="#sec-http-how-impl" class="quarto-xref"><span>Section 7.3</span></a>, every socket object that we create represents a communication channel, and we need to bind this channel to a specific address. An “address” is defined as an IP address, or, more specifically, an IPv4 address<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>. Every IPv4 address is composed by two components. The first component is the host, which is a sequence of 4 numbers separated by dot characters (<code>.</code>) that identifies the machine used. While the second component is a port number, which identifies the specific door, or, the specific port to use in the host machine.</p>
<p>The sequence of 4 numbers (i.e., the host) identifies the machine (i.e., the computer itself) where this socket will live in. Every computer normally have multiple “doors” available inside of him, because this allows the computer to receive and work with multiple connections at the same time. He simply use a single door for each connection. So the port number, is essentially a number that identifies the “door” in the computer that the socket will use to receive incoming connections.</p>
<p>To make things simpler, I will use an IP address that identifies our current machine in this example. This means that, our socket object will reside on the same computer that we are currently using (this is also known as the “localhost”) to write this Zig source code. By convention, the IP address that identifies the “localhost”, which is the current machine we are using, is the IP <code>127.0.0.1</code>. So, that is the IP address we are going to use in our server.</p>
<p>Now, we need to decide which port number to use. By convention, there are some port numbers that are reserved, meaning that, we cannot use them for our own purposes, like the port 22 (which is normally used for SSH connections). For TCP connections, which is our case here, a port number is a 16-bit unsigned integer (type <code>u16</code> in Zig), thus ranging from 0 to 65535 <span class="citation" data-cites="wikipedia_port">(<a href="references.html#ref-wikipedia_port" role="doc-biblioref">Wikipedia 2024</a>)</span>. So, we can choose a number from 0 to 65535 for our port number. In the example of this book, I will use the port number 3490 (just a random number).</p>
<p>All of this process and steps that we’ve described are concentrated inside our own custom struct called <code>Server</code>, which is exposed below. Notice that we create a new <code>std.Io.net.IpAddress</code> object inside this struct. We also create our <code>std.Io.net.Server</code> object through the <code>listen()</code> method from our IP address object.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb1"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Socket = std.Io.net.Socket;</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Protocol = std.Io.net.Protocol;</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">const</span> Server = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    host: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    port: <span class="dt">u16</span>,</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    addr: std.Io.net.IpAddress,</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    io: std.Io,</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> init(io: std.Io) !Server <span class="op">{</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> host: []<span class="kw">const</span> <span class="dt">u8</span> = <span class="st">"127.0.0.1"</span>;</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> port: <span class="dt">u16</span> = <span class="dv">3490</span>;</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> addr = <span class="kw">try</span> std.Io.net.IpAddress.parseIp4(</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>            host, port</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        );</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> .<span class="op">{</span>.host=host, .port=port, .addr=addr, .io=io<span class="op">}</span>;</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> listen(self: Server) !std.Io.net.Server <span class="op">{</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>        std.debug.print(<span class="st">"Server Addr: {s}:{any}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>self.host, self.port<span class="op">}</span>);</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">try</span> self.addr.listen(</span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>            self.io,</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>            .<span class="op">{</span>.mode=Socket.Mode.stream, .protocol=Protocol.tcp<span class="op">}</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>        );</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
</section>
<section id="listening-and-receiving-connections" class="level3" data-number="7.4.2">
<h3 data-number="7.4.2" class="anchored" data-anchor-id="listening-and-receiving-connections"><span class="header-section-number">7.4.2</span> Listening and receiving connections</h3>
<p>Remember that our <code>Server</code> struct declaration that we’ve built in <a href="#sec-create-socket" class="quarto-xref"><span>Section 7.4.1</span></a> is inside a Zig module named <code>server.zig</code>. This is why I have imported this module into our main module (<code>main.zig</code>) in the example below, to access our <code>Server</code> struct.</p>
<p>Now, the socket stored inside our <code>Server</code> object needs to start listening and accepting new connections. We can do that by calling the method <code>listen()</code> from it, and then, calling the <code>accept()</code> method from the result. If you run the main module exposed below, you will notice that the program never ends. It just keeps stuck.</p>
<p>This happens, because the program is waiting for something to happen. It’s waiting for someone to try to connect to the address (<code>127.0.0.1:3490</code>) where the server is running and listening for incoming connections. This is what the <code>listen()</code> method do, it makes the socket to be active waiting for someone to connect.</p>
<p>On the other side, the <code>accept()</code> method is the function that establishes the connection when someone tries to connect to the socket. This means that, the <code>accept()</code> method returns a new connection object as a result. And you can use this connection object to read or write messages from or to the client. For now, we are not doing anything with this connection object. But we are going to use it in the next section.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb2"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Server = <span class="bu">@import</span>(<span class="st">"server.zig"</span>).Server;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> alloc = std.heap.GeneralPurposeAllocator(.<span class="op">{}</span>)<span class="op">{}</span>;</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> gpa = alloc.allocator();</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> threaded: std.Io.Threaded = .init(gpa);</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> io = threaded.io();</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> threaded.deinit();</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> server = <span class="kw">try</span> Server.init(io);</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> listening = <span class="kw">try</span> server.listen();</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> connection = <span class="kw">try</span> listening.accept(io);</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> connection.close(io);</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>This code example allows one single connection. In other words, the server will wait for one incoming connection, and as soon as the server is done with this first connection that it establishes, the program ends, and the server stops.</p>
<p>This is not the norm in the real world. Most people that write a HTTP server like this, usually put the <code>accept()</code> method inside a <code>while</code> (infinite) loop, where if a connection is created with <code>accept()</code>, a new thread of execution is created to deal with this new connection and the client. That is, real-world examples of HTTP Servers normally rely on parallel computing to work.</p>
<p>With this design, the server simply accepts the connection, and the whole process of dealing with the client, and receiving the HTTP Request, and sending the HTTP Response, all of this is done in the background, on a separate execution thread.</p>
<p>So, as soon as the server accepts the connection, and creates the separate thread, the server goes back to what he was doing earlier, which is to wait indefinitely for a new connection to accept. Having this in mind, the code example exposed above, is a server that serves only a single client. Because the program terminates as soon as the connection is accepted.</p>
</section>
<section id="sec-read-http-message" class="level3" data-number="7.4.3">
<h3 data-number="7.4.3" class="anchored" data-anchor-id="sec-read-http-message"><span class="header-section-number">7.4.3</span> Reading the message from the client</h3>
<p>Now that we have a connection established, i.e., the connection object that we created through the <code>accept()</code> function, we can now use this connection object to read any messages that the client send to our server. But we can also use it to send messages back to the client.</p>
<p>The basic idea is, if we <strong>write</strong> any data into this connection object, then, we are sending data to the client, and if we <strong>read</strong> the data present in this connection object, then, we are reading any data that the client sent to us, through this connection object. So, just have this logic in mind. “Read” is for reading messages from the client, and “write” is to send a message to the client.</p>
<p>Remember from <a href="#sec-how-http-works" class="quarto-xref"><span>Section 7.2</span></a> that, the first thing that we need to do is to read the HTTP Request sent by the client to our server. Because it is the first message that happens inside the established connection, and, as a consequence, it is the first thing that we need to deal with.</p>
<p>That is why, I’m going to create a new Zig module in this small project, named <code>request.zig</code> to keep all functions related to the HTTP Request together. Then, I will create a new function named <code>read_request()</code> that will use our connection object to read the message sent by the client, which is the HTTP Request.</p>
<p>You can see below that our <code>read_request()</code> function receives three inputs. The <code>io</code> argument should receive the IO backend that we want to use in our IO operations. The <code>conn</code> argument receives the connection object that we generated through the <code>accept()</code> method. While the <code>buffer</code> argument receives the buffer object in which we are going to store the request that the client have sent to our server.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb3"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Stream = std.Io.net.Stream;</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> read_request(io: std.Io, conn: Stream, buffer: []<span class="dt">u8</span>) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> recv_buffer: [<span class="dv">1024</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> reader = conn.reader(io, &amp;recv_buffer);</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> reader_interface = &amp;reader.interface;</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> start_index: <span class="dt">usize</span> = <span class="dv">0</span>;</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> (<span class="dv">0</span>..<span class="dv">5</span>) |_| <span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> len = <span class="kw">try</span> read_next_line(reader_interface, buffer, start_index);</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>        start_index += len;</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="kw">fn</span> read_next_line(reader: *std.Io.Reader, buffer: []<span class="dt">u8</span>, start_index: <span class="dt">usize</span>) !<span class="dt">usize</span> <span class="op">{</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> next_line = <span class="kw">try</span> reader.takeDelimiterInclusive(<span class="ch">'\n'</span>);</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>    <span class="bu">@memcpy</span>(</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        buffer[start_index..(start_index + next_line.len)],</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>        next_line[<span class="dv">0</span>..],</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> next_line.len;</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>So, the <code>read_request()</code> function essentially receives a connection object as input, which is represented by an IO stream object, then, it reads the HTTP request sent by the client by “reading data from the IO stream”, and saves this message into this buffer object that we have provided as input.</p>
<p>In order to do that, I first create a <code>reader</code> object from the IO stream object. Then, I call the <code>takeDelimiterInclusive()</code> method of this <code>reader</code> object, together with <code>@memcpy()</code>, to effectively read the next line of data from the stream. The for loop present in <code>read_request()</code> repeats this process 6 times, so, we are effectively reading the 6 first lines of the HTTP Request, and saving this data into the buffer object that we’ve created earlier.</p>
</section>
</section>
<section id="looking-at-the-current-state-of-the-program" class="level2" data-number="7.5">
<h2 data-number="7.5" class="anchored" data-anchor-id="looking-at-the-current-state-of-the-program"><span class="header-section-number">7.5</span> Looking at the current state of the program</h2>
<p>I think now is a good time to see how our program is currently working. Shall we? So, the first thing I will do is to update the <code>main.zig</code> module in our small Zig project, so that the <code>main()</code> function call this new <code>read_request()</code> function that we have just created. I will also add a print statement at the end of the <code>main()</code> function, just so that you can see what the HTTP Request that we have just loaded into the buffer object looks like.</p>
<p>Also, I’m creating the buffer object (<code>request_buffer</code>) in the <code>main()</code> function, which will be responsible for storing the message sent by the client, and, I’m also using <code>@memset()</code> to initialize the entire buffer object to zero. This is important to make sure that we don’t have uninitialized memory in this object. Because uninitialized memory may cause undefined behaviour in our program.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb4"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Request = <span class="bu">@import</span>(<span class="st">"request.zig"</span>);</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Server = <span class="bu">@import</span>(<span class="st">"server.zig"</span>).Server;</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> alloc = std.heap.GeneralPurposeAllocator(.<span class="op">{}</span>)<span class="op">{}</span>;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> gpa = alloc.allocator();</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> threaded: std.Io.Threaded = .init(gpa);</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> io = threaded.io();</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> threaded.deinit();</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> server = <span class="kw">try</span> Server.init(io);</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> listening = <span class="kw">try</span> server.listen();</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> connection = <span class="kw">try</span> listening.accept(io);</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> connection.close(io);</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> request_buffer: [<span class="dv">1000</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    <span class="bu">@memset</span>(request_buffer[<span class="dv">0</span>..], <span class="dv">0</span>);</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> Request.read_request(</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>        io,</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>        connection,</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>        request_buffer[<span class="dv">0</span>..]</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>    std.debug.print(<span class="st">"{s}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>request_buffer<span class="op">}</span>);</span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Now, I’m going to execute this program, with the <code>run</code> command from the <code>zig</code> compiler. But remember, as we sad earlier, as soon as I execute this program, it will hang indefinitely, because the program is waiting for a client trying to connect to the server.</p>
<p>More specifically, the program will pause at the line with the <code>accept()</code> call. As soon as a client try to connect to the server, then, the execution will “unpause”, and the <code>accept()</code> function will finally be executed to create the connection object that we need, and the remaining of the program will run.</p>
<p>You can see that in <a href="#fig-print-zigrun1" class="quarto-xref">Figure&nbsp;<span>7.1</span></a>. The message <code>Server Addr: 127.0.0.1:3490</code> is printed to the console, and the program is now waiting for an incoming connection.</p>
<div id="fig-print-zigrun1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-print-zigrun1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="./../Figures/print-zigrun1.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-print-zigrun1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;7.1: A screenshot of running the program
</figcaption>
</figure>
</div>
<p>We can finally try to connect to this server, and there are several ways we can do this. For example, we could use the following Python script:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> requests</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>requests.get(<span class="st">"http://127.0.0.1:3490"</span>)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<p>Or, we could also open any web browser of our preference, and type the URL <code>localhost:3490</code>. OBS: <code>localhost</code> is the same thing as the IP <code>127.0.0.1</code>. When you press enter, and your web browser go to this address, first, the browser will probably print a message saying that “this page isn’t working”, and, then, it will probably change to a new message saying that “the site can’t be reached”.</p>
<p>You get these “error messages” in the web browser, because it got no response back from the server. In other words, when the web browser connected to our server, it did send the HTTP request through the established connection. Then, the web browser was expecting to receive a HTTP response back, but it got no response from the server (we didn’t implemented the HTTP Response logic yet).</p>
<p>But that is okay. We have achieved the result that we wanted for now, which is to connect to the server, and see the HTTP request that was sent by the web browser (or by the Python script) to the server.</p>
<p>If you comeback to the console that you left open when you have executed the program, you will see that the program finished its execution, and, a new message is printed in the console, which is the actual HTTP request message that was sent by the web browser to the server.</p>
<p>Since we are only reading the first 6 lines of the HTTP request in our code, this program might not print the entire HTTP request message to you. That will depend on how big the HTTP request message was. You can see the HTTP request printed in <a href="#fig-print-zigrun2" class="quarto-xref">Figure&nbsp;<span>7.2</span></a>.</p>
<div id="fig-print-zigrun2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-print-zigrun2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="./../Figures/print-zigrun2.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-print-zigrun2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;7.2: A screenshot of the HTTP Request sent by the web browser
</figcaption>
</figure>
</div>
</section>
<section id="sec-enum" class="level2" data-number="7.6">
<h2 data-number="7.6" class="anchored" data-anchor-id="sec-enum"><span class="header-section-number">7.6</span> Learning about Enums in Zig</h2>
<p>Enums structures are available in Zig through the <code>enum</code> keyword. An enum (short for “enumeration”) is a special structure that represents a group of constant values. So, if you have a variable which can assume a short and known set of values, you might want to associate this variable to an enum structure, to make sure that this variable only assumes a value from this set.</p>
<p>A classic example for enums are primary colors. If for some reason, your program needs to represent one of the primary colors, you can create an enum that represents one of these colors. In the example below, we are creating the enum <code>PrimaryColorRGB</code>, which represents a primary color from the RGB color system. By using this enum, I am guaranteed that the <code>acolor</code> object for example, will contain one of these three values: <code>RED</code>, <code>GREEN</code> or <code>BLUE</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb6"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> PrimaryColorRGB = <span class="kw">enum</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    RED, GREEN, BLUE</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> acolor = PrimaryColorRGB.RED;</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>_ = acolor;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>If for some reason, my code tries to save in <code>acolor</code>, a value that is not in this set, I will get an error message warning me that a value such as “MAGENTA” do not exist inside the <code>PrimaryColorRGB</code> enum. Then I can easily fix my mistake.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb7"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> acolor = PrimaryColorRGB.MAGENTA;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>e1.zig:5:36: error: enum 'PrimaryColorRGB' has
        no member named 'MAGENTA':
    const acolor = PrimaryColorRGB.MAGENTA;
                                   ^~~~~~~</code></pre>
<p>Behind the hood, enums in Zig work the same way that enums work in C. Each enum value is essentially represented as an integer. The first value in the set is represented as zero, then, the second value is one, … etc.</p>
<p>One thing that we are going to learn in the next section is that enums can have methods in them. Wait… What? This is amazing! Yes, enums in Zig are similar to structs, and they can have private and public methods inside them.</p>
</section>
<section id="implementing-the-server---part-2" class="level2" data-number="7.7">
<h2 data-number="7.7" class="anchored" data-anchor-id="implementing-the-server---part-2"><span class="header-section-number">7.7</span> Implementing the server - Part 2</h2>
<p>Now, on this section, I want to focus on parsing the HTTP Request that we received from the client. However, to effectively parse a HTTP Request message, we first need to understand its structure. In summary, a HTTP Request is a text message that is divided into 3 different sections (or parts):</p>
<ul>
<li>The top-level header indicating the method of the HTTP Request, the URI, and the HTTP version used in the message.</li>
<li>A list of HTTP Headers.</li>
<li>The body of the HTTP Request.</li>
</ul>
<section id="the-top-level-header" class="level3" data-number="7.7.1">
<h3 data-number="7.7.1" class="anchored" data-anchor-id="the-top-level-header"><span class="header-section-number">7.7.1</span> The top-level header</h3>
<p>The first line of text in a HTTP Request always come with the three most essential information about the request. These three key attributes of the HTTP Request are separated by a simple space in this first line of the request. The first information is the HTTP method that is being used in the request, second, we have the URI to which this HTTP Request is being sent to, and third, we have the version of the HTTP protocol that is being used in this HTTP Request.</p>
<p>In the snippet below, you can find an example of this first line in a HTTP Request. First, we have the HTTP method of this request (<code>GET</code>). Many programmers refer to the URI component (<code>/users/list</code>) as the “API endpoint” to which the HTTP Request is being sent to. In the context of this specific request, since it’s a GET request, you could also say that the URI component is the path to the resource we want to access, or, the path to the document (or the file) that we want to retrieve from the server.</p>
<pre><code>GET /users/list HTTP/1.1</code></pre>
<p>Also, notice that this HTTP Request is using the version 1.1 of the HTTP protocol, which is the most popular version of the protocol used in the web.</p>
</section>
<section id="the-list-of-http-headers" class="level3" data-number="7.7.2">
<h3 data-number="7.7.2" class="anchored" data-anchor-id="the-list-of-http-headers"><span class="header-section-number">7.7.2</span> The list of HTTP headers</h3>
<p>Most HTTP Requests also include a section of HTTP Headers, which is just a list of attributes or key-value pairs associated with this particular request. This section always comes right after the “top-level header” of the request.</p>
<p>For our purpose in this chapter, which is to build a simple HTTP Server, we are going to ignore this section of the HTTP Request, for simplicity. But most HTTP servers that exist in the wild parses and use these HTTP headers to change the way that the server responds to the request sent by the client.</p>
<p>For example, many requests we encounter in the real-world comes with a HTTP header called <code>Accept</code>. In this header, we find a list of <a href="https://en.wikipedia.org/wiki/Media_type">MIME types</a><a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>. This list indicates the file formats that the client can read, or parse, or interpret. In other words, you also interpret this header as the client saying the following phrase to the server: “Hey! Look, I can read only HTML documents, so please, send me back a document that is in a HTML format.”.</p>
<p>If the HTTP server can read and use this <code>Accept</code> header, then, the server can identify which is the best file format for the document to be sent to the client. Maybe the HTTP server have the same document in multiple formats, for example, in JSON, in XML, in HTML and in PDF, but the client can only understand documents in the HTML format. That is the purpose of this <code>Accept</code> header.</p>
</section>
<section id="the-body" class="level3" data-number="7.7.3">
<h3 data-number="7.7.3" class="anchored" data-anchor-id="the-body"><span class="header-section-number">7.7.3</span> The body</h3>
<p>The body comes after the list of HTTP headers, and it’s an optional section of the HTTP Request, meaning that, not all HTTP Requests will come with a body in them. For example, every HTTP Request that uses the GET method usually does not come with a body.</p>
<p>Because a GET request is used to request data, instead of sending it to the server. So, the body section is more related to the POST method, which is a method that involves sending data to the server, to be processed and stored.</p>
<p>Since we are going to support only the GET method in this project, it means that we also do not need to care about the body of the request.</p>
</section>
<section id="creating-the-http-method-enum" class="level3" data-number="7.7.4">
<h3 data-number="7.7.4" class="anchored" data-anchor-id="creating-the-http-method-enum"><span class="header-section-number">7.7.4</span> Creating the HTTP Method enum</h3>
<p>Every HTTP Request comes with a explicit method. The method used in a HTTP Request is identified by one these words:</p>
<ul>
<li>GET;</li>
<li>POST;</li>
<li>OPTIONS;</li>
<li>PATCH;</li>
<li>DELETE;</li>
<li>and some other methods.</li>
</ul>
<p>Each HTTP method is used for a specific type of task. The POST method for example is normally used to post some data into the destination. In other words, it’s used to send some data to the HTTP server, so that it can be processed and stored by the server.</p>
<p>As another example, the GET method is normally used to get content from the server. In other words, we use this method whenever we want the server to send some content back to us. It can be any type of content. It can be a web page, a document file, or some data in a JSON format.</p>
<p>When a client sends a POST HTTP Request, the HTTP Response sent by the server normally have the sole purpose of letting the client know if the server processed and stored the data successfully. In contrast, when the server receives a GET HTTP Request, then, the server sends the content that the client asked for in the HTTP Response itself. This demonstrates that the method associated with the HTTP Request changes a lot on the dynamics and the roles that each party plays in the whole process.</p>
<p>Since the HTTP method of the HTTP Request is identified by this very small and specific set of words, it would be interesting to create an enum structure to represent a HTTP method. This way, we can easily check if the HTTP Request we receive from the client is a HTTP method that we currently support in our small HTTP server project.</p>
<p>The <code>Method</code> structure below represents this enumeration. Notice that, for now, only the GET HTTP method is included in this enumeration. Because, for the purpose of this chapter, I want to implement only the GET HTTP method. That is why I am not including the other HTTP methods in this enumeration.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb10"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">const</span> Method = <span class="kw">enum</span> <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    GET</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Now, I think we should add two methods to this enum structure. One method is <code>is_supported()</code>, which will be a function that returns a boolean value, indicating if the input HTTP method is supported or not by our HTTP Server. The other is <code>init()</code>, which is a constructor function that takes a string as input, and tries to convert it into a <code>Method</code> value.</p>
<p>But in order to build these functions, I will use a functionality from the Zig Standard Library, called <code>StaticStringMap()</code>. This function allows us to create a simple map from strings to enum values. In other words, we can use this map structure to map a string to the respective enum value. To some extent, this specific structure from the standard library works almost like a “hashtable” structure, and it’s optimized for small sets of words, or, small sets of keys, which is our case here. We are going to talk more about hashtables in Zig in <a href="09-data-structures.html#sec-maps-hashtables" class="quarto-xref"><span>Section 11.2</span></a>.</p>
<p>To use this “static string map” structure, you have to import it from the <code>std.static_string_map</code> module of the Zig Standard Library. Just to make things shorter and easier to type, I am going to import this function through a different and shorter name (<code>Map</code>).</p>
<p>With <code>Map()</code> imported, we can just apply this function over the enum structure that we are going to use in the resulting map. In our case here, it’s the <code>Method</code> enum structure that we declared at the last code example. Then, I call the <code>initComptime()</code> method with the map, i.e., the list of key-value pairs that we are going to use.</p>
<p>You can see in the example below that I wrote this map using multiple anonymous struct literals. Inside the first (or “top-level”) struct literal, we have a list (or a sequence) of struct literals. Each struct literal in this list represents a separate key-value pair. The first element (or the key) in each key-value pair should always be a string value. While the second element should be a value from the enum structure that you have used inside the <code>Map()</code> function.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb11"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Map = std.static_string_map.StaticStringMap;</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> MethodMap = Map(Method).initComptime(.<span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    .<span class="op">{</span> <span class="st">"GET"</span>, Method.GET <span class="op">}</span>,</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>);</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Therefore, the <code>MethodMap</code> object is basically a <code>std::map</code> object from C++, or, a <code>dict</code> object from Python. You can retrieve (or get) the enum value that corresponds to a particular key, by using the <code>get()</code> method from the map object. This method returns an optional value, so, the <code>get()</code> method might result in a null value.</p>
<p>We can use this in our advantage to detect if a particular HTTP method is supported or not in our HTTP server. Because, if the <code>get()</code> method returns null, it means that it did not found the method that we provided inside the <code>MethodMap</code> object, and, as a consequence, this method is not supported by our HTTP server.</p>
<p>The <code>init()</code> method below, takes a string value as input, and then, it simply passes this string value to the <code>get()</code> method of our <code>MethodMap</code> object. As consequence, we should get the enum value that corresponds to this input string.</p>
<p>Notice in the example below that, the <code>init()</code> method returns either an error (which might happen if the <code>?</code> method returns <code>unreacheable</code>, checkout <a href="05-pointers.html#sec-null-handling" class="quarto-xref"><span>Section 6.4.3</span></a> for more details) or a <code>Method</code> object as result. Since <code>GET</code> is currently the only value in our <code>Method</code> enum structure, it means that, the <code>init()</code> method will most likely return the value <code>Method.GET</code> as result.</p>
<p>Also notice that, in the <code>is_supported()</code> method, we are using the optional value returned by the <code>get()</code> method from our <code>MethodMap</code> object. The if statement unwraps the optional value returned by this method, and returns <code>true</code> in case this optional value is a not-null value. Otherwise, it simply returns <code>false</code>.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb12"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">const</span> Method = <span class="kw">enum</span> <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    GET,</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> init(text: []<span class="kw">const</span> <span class="dt">u8</span>) !Method <span class="op">{</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> MethodMap.get(text).?;</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> is_supported(m: []<span class="kw">const</span> <span class="dt">u8</span>) <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">const</span> method = MethodMap.get(m);</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> (method) |_| <span class="op">{</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="cn">true</span>;</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="cn">false</span>;</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
</section>
<section id="writing-the-parse-request-function" class="level3" data-number="7.7.5">
<h3 data-number="7.7.5" class="anchored" data-anchor-id="writing-the-parse-request-function"><span class="header-section-number">7.7.5</span> Writing the parse request function</h3>
<p>Now that we created the enum that represents our HTTP method, we should start to write the function responsible for actually parsing the HTTP Request.</p>
<p>The first thing we can do, is to write a struct to represent the HTTP Request. Take the <code>Request</code> struct below as an example. It contains the three essential information from the “top-level” header (i.e., the first line) in the HTTP Request.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb13"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Request = <span class="kw">struct</span> <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    method: Method,</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    version: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    uri: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">pub</span> <span class="kw">fn</span> init(method: Method,</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>                uri: []<span class="kw">const</span> <span class="dt">u8</span>,</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>                version: []<span class="kw">const</span> <span class="dt">u8</span>) Request <span class="op">{</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> Request<span class="op">{</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>            .method = method,</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>            .uri = uri,</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>            .version = version,</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span>;</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>;</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>The <code>parse_request()</code> function should receive a string as input. This input string contains the HTTP Request message, and the parsing function should read and understand the individual parts of this message.</p>
<p>Now, remember that for the purpose of this chapter, we care only about the first line in this message, which contains the “top-level header”, or, the three essential attributes about the HTTP Request, which are the HTTP method used, the URI and the HTTP version.</p>
<p>Notice that I use the function <code>indexOfScalar()</code> in <code>parse_request()</code>. This function from the Zig Standard Library returns the first index where the scalar value that we provide happens in a string. In this case, I’m looking at the first occurrence of the new line character (<code>\n</code>). Because once again, we care only about the first line in the HTTP Request message. This is the line where we have the three information that we want to parse (version of HTTP, the HTTP method and the URI).</p>
<p>Therefore, we are using this <code>indexOfScalar()</code> function to limit our parsing process to the first line in the message. It’s also worth mentioning that, the <code>indexOfScalar()</code> function returns an optional value. That is why I use the <code>orelse</code> keyword to provide an alternative value, in case the value returned by the function is a null value.</p>
<p>Since each of these three attributes are separated by a simple space, we could use the function <code>splitScalar()</code> from the Zig Standard Library to split the input string into sections by looking for every position that appears a simple space. In other words, this <code>splitScalar()</code> function is equivalent to the <code>split()</code> method in Python, or, the <code>std::getline()</code> function from C++, or the <code>strtok()</code> function in C.</p>
<p>When you use this <code>splitScalar()</code> function, you get an iterator as the result. This iterator have a <code>next()</code> method that you can use to advance the iterator to the next position, or, to the next section of the splitted string. Note that, when you use <code>next()</code>, the method not only advances the iterator, but it also returns a slice to the current section of the splitted string as result.</p>
<p>Now, if you want to get a slice to the current section of the splitted string, but not advance the iterator to the next position, you can use the <code>peek()</code> method. Both <code>next()</code> and <code>peek()</code> methods return an optional value, that is why I use the <code>?</code> method to unwrap these optional values.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb14"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> parse_request(text: []<span class="dt">u8</span>) Request <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> line_index = std.mem.indexOfScalar(</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">u8</span>, text, <span class="ch">'\n'</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    ) <span class="kw">orelse</span> text.len;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> iterator = std.mem.splitScalar(</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">u8</span>, text[<span class="dv">0</span>..line_index], <span class="ch">' '</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> method = <span class="kw">try</span> Method.init(iterator.next().?);</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> uri = iterator.next().?;</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> version = iterator.next().?;</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> request = Request.init(method, uri, version);</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> request;</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>As I described in <a href="01-zig-weird.html#sec-zig-strings" class="quarto-xref"><span>Section 1.8</span></a>, strings in Zig are simply arrays of bytes in the language. So, you will find lots of excellent utility functions to work directly with strings inside this <code>mem</code> module from the Zig Standard Library. We have described some of these useful utility functions already in <a href="01-zig-weird.html#sec-strings-useful-funs" class="quarto-xref"><span>Section 1.8.5</span></a>.</p>
</section>
<section id="using-the-parse-request-function" class="level3" data-number="7.7.6">
<h3 data-number="7.7.6" class="anchored" data-anchor-id="using-the-parse-request-function"><span class="header-section-number">7.7.6</span> Using the parse request function</h3>
<p>Now that we wrote the function responsible for parsing the HTTP Request, we can add the function call to <code>parse_request()</code> in the <code>main()</code> function of our program.</p>
<p>After that, is a good idea to test once again the state of our program. I execute this program again with the <code>run</code> command from the <code>zig</code> compiler, then, I use my web browser to connect once again to the server through the URL <code>localhost:3490</code>, and finally, the end result of our <code>Request</code> object is printed to the console.</p>
<p>A quick observation, since I have used the <code>any</code> format specifier in the print statement, the data members <code>version</code> and <code>uri</code> of the <code>Request</code> struct were printed as raw integer values. String data being printed as integer values is common in Zig, and remember, these integer values are just the decimal representation of the bytes that form the string in question.</p>
<p>In the result below, the sequence of decimal values 72, 84, 84, 80, 47, 49, 46, 49, and 13, are the bytes that form the text “HTTP/1.1”. And the integer 47, is the decimal value of the character <code>/</code>, which represents our URI in this request.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb15"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Request = <span class="bu">@import</span>(<span class="st">"request.zig"</span>);</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Server = <span class="bu">@import</span>(<span class="st">"server.zig"</span>).Server;</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> alloc = std.heap.GeneralPurposeAllocator(.<span class="op">{}</span>)<span class="op">{}</span>;</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> gpa = alloc.allocator();</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> server = <span class="kw">try</span> Server.init(io);</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> listening = <span class="kw">try</span> server.listen();</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> connection = <span class="kw">try</span> listening.accept(io);</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> connection.close(io);</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> request_buffer: [<span class="dv">1000</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>    <span class="bu">@memset</span>(request_buffer[<span class="dv">0</span>..], <span class="dv">0</span>);</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> Request.read_request(</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>        io,</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>        connection,</span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>        request_buffer[<span class="dv">0</span>..]</span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> request = Request.parse_request(request_buffer[<span class="dv">0</span>..]);</span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a>    std.debug.print(<span class="st">"{any}</span><span class="sc">\n</span><span class="st">"</span>, .<span class="op">{</span>request<span class="op">}</span>);</span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<pre><code>request.Request{
    .method = request.Method.GET,
    .version = {72, 84, 84, 80, 47, 49, 46, 49, 13},
    .uri = {47}
}</code></pre>
</section>
<section id="sending-the-http-response-to-the-client" class="level3" data-number="7.7.7">
<h3 data-number="7.7.7" class="anchored" data-anchor-id="sending-the-http-response-to-the-client"><span class="header-section-number">7.7.7</span> Sending the HTTP Response to the client</h3>
<p>In this last part, we are going to write the logic responsible for sending the HTTP Response from the server to the client. To make things simple, the server in this project will send just a simple web page containing the text “Hello world”.</p>
<p>First, I create a new Zig module in the project, named <code>response.zig</code>. In this module, I will declare just two functions. Each function corresponds to a specific status code in the HTTP Response. The <code>send_200()</code> function will send a HTTP Response with status code 200 (which means “Success”) to the client. While the <code>send_404()</code> function sends a response with status code 404 (which means “Not found”).</p>
<p>This is definitely not the most ergonomic and adequate way of handling the HTTP Response, but it works for our case here. We are just building toy projects in this book after all, therefore, the source code that we write do not need to be perfect. It just needs to work!</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb17"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Stream = std.Io.net.Stream;</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> send_200(conn: Stream, io: std.Io) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> message = (</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>        <span class="st">"HTTP/1.1 200 OK</span><span class="sc">\n</span><span class="st">Content-Length: 48"</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"</span><span class="sc">\n</span><span class="st">Content-Type: text/html</span><span class="sc">\n</span><span class="st">"</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"Connection: Closed</span><span class="sc">\n\n</span><span class="st">&lt;html&gt;&lt;body&gt;"</span></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"&lt;h1&gt;Hello, World!&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;"</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> stream_writer = conn.writer(io, &amp;.<span class="op">{}</span>);</span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a>    _ = <span class="kw">try</span> stream_writer.interface.write(message);</span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> send_404(conn: Stream, io: std.Io) !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> message = (</span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>        <span class="st">"HTTP/1.1 404 Not Found</span><span class="sc">\n</span><span class="st">Content-Length: 50"</span></span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"</span><span class="sc">\n</span><span class="st">Content-Type: text/html</span><span class="sc">\n</span><span class="st">"</span></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"Connection: Closed</span><span class="sc">\n\n</span><span class="st">&lt;html&gt;&lt;body&gt;"</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>        ++ <span class="st">"&lt;h1&gt;File not found!&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;"</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> stream_writer = conn.writer(io, &amp;.<span class="op">{}</span>);</span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a>    _ = <span class="kw">try</span> stream_writer.interface.write(message);</span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Notice that both functions receives the connection object as input, creates a writer object from this connection object, then, uses the <code>write()</code> method to write the HTTP Response message directly into this communication channel. As result, the party in the other side of the connection (i.e., the client), will receive such message.</p>
<p>Most real-world HTTP Servers will have a single function (or a single struct) to effectively handle the response. It gets the HTTP Request already parsed as input, and then, it tries to build the HTTP Response bit by bit, before the function sends it over the connection.</p>
<p>We would also have a specialized struct to represent a HTTP Response, and a lot of methods that would be used to build each part or component of the response object. Take the <code>Response</code> struct created by the Javascript runtime Bun as an example. You can find this struct in the <a href="https://github.com/oven-sh/bun/blob/main/src/bun.js/webcore/response.zig"><code>response.zig</code> module</a><a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> in their GitHub project.</p>
</section>
</section>
<section id="the-end-result" class="level2" data-number="7.8">
<h2 data-number="7.8" class="anchored" data-anchor-id="the-end-result"><span class="header-section-number">7.8</span> The end result</h2>
<p>We can now, update once again our <code>main()</code> function to incorporate our new functions from the <code>response.zig</code> module. First, I need to import this module into our <code>main.zig</code> module, then, I add the function calls to <code>send_200()</code> and <code>send_404()</code>.</p>
<p>Notice that I’m using if statements to decide which “response function” to call, based especially on the URI present in the HTTP Request. If the user asked for a content (or a document) that is not present in our server, we should respond with a 404 status code. But since we have just a simple HTTP server, with no real documents to send, we can just check if the URI is the root path (<code>/</code>) or not to decide which function to call.</p>
<p>Also, notice that I’m using the function <code>std.mem.eql()</code> from the Zig Standard Library to check if the string from <code>uri</code> is equal or not the string <code>"/"</code>. We have described this function already in <a href="01-zig-weird.html#sec-strings-useful-funs" class="quarto-xref"><span>Section 1.8.5</span></a>, so, comeback to that section if you are not familiar yet with this function.</p>
<div class="cell">
<div class="sourceCode cell-code" id="cb18"><pre class="sourceCode zig code-with-copy"><code class="sourceCode zig"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> std = <span class="bu">@import</span>(<span class="st">"std"</span>);</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Request = <span class="bu">@import</span>(<span class="st">"request.zig"</span>);</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Response = <span class="bu">@import</span>(<span class="st">"response.zig"</span>);</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> Server = <span class="bu">@import</span>(<span class="st">"server.zig"</span>).Server;</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="kw">pub</span> <span class="kw">fn</span> main() !<span class="dt">void</span> <span class="op">{</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> alloc = std.heap.GeneralPurposeAllocator(.<span class="op">{}</span>)<span class="op">{}</span>;</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> gpa = alloc.allocator();</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> threaded: std.Io.Threaded = .init(gpa);</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> io = threaded.io();</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> threaded.deinit();</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> server = <span class="kw">try</span> Server.init(io);</span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> listening = <span class="kw">try</span> server.listen();</span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> connection = <span class="kw">try</span> listening.accept(io);</span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">defer</span> connection.close(io);</span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> request_buffer: [<span class="dv">1000</span>]<span class="dt">u8</span> = <span class="cn">undefined</span>;</span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a>    <span class="bu">@memset</span>(request_buffer[<span class="dv">0</span>..], <span class="dv">0</span>);</span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span> Request.read_request(</span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a>        io,</span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a>        connection,</span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>        request_buffer[<span class="dv">0</span>..]</span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> request = Request.parse_request(request_buffer[<span class="dv">0</span>..]);</span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> (request.method == Method.GET) <span class="op">{</span></span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> (std.mem.eql(<span class="dt">u8</span>, request.uri, <span class="st">"/"</span>)) <span class="op">{</span></span>
<span id="cb18-28"><a href="#cb18-28" aria-hidden="true" tabindex="-1"></a>            <span class="kw">try</span> Response.send_200(connection, io);</span>
<span id="cb18-29"><a href="#cb18-29" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="kw">else</span> <span class="op">{</span></span>
<span id="cb18-30"><a href="#cb18-30" aria-hidden="true" tabindex="-1"></a>            <span class="kw">try</span> Response.send_404(connection, io);</span>
<span id="cb18-31"><a href="#cb18-31" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-32"><a href="#cb18-32" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-33"><a href="#cb18-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</div>
<p>Now that we adjusted our <code>main()</code> function, I can now execute our program, and see the effects of these last changes. First, I execute the program once again, with the <code>run</code> command of the <code>zig</code> compiler. The program will hang, waiting for a client to connect.</p>
<p>Then, I open my web browser, and try to connect to the server again, using the URL <code>localhost:3490</code>. This time, instead of getting some sort of an error message from the browser, you will get the message “Hello World” printed into your web browser. Because this time, the server sended the HTTP Response successfully to the web browser, as demonstrated by <a href="#fig-print-zigrun3" class="quarto-xref">Figure&nbsp;<span>7.3</span></a>.</p>
<div id="fig-print-zigrun3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-print-zigrun3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="./../Figures/print-zigrun3.png" class="img-fluid figure-img">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-print-zigrun3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;7.3: The Hello World message sent in the HTTP Response
</figcaption>
</figure>
</div>


<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" role="list" style="display: none">
<div id="ref-eric_http" class="csl-entry" role="listitem">
Meehan, Eric. 2021. <span>“Creating a Web Server from Scratch in c.”</span> Youtube. <a href="https://www.youtube.com/watch?v=gk6NL1pZi1M&amp;ab_channel=EricOMeehan">https://www.youtube.com/watch?v=gk6NL1pZi1M&amp;ab_channel=EricOMeehan</a>.
</div>
<div id="ref-nipun_http" class="csl-entry" role="listitem">
Weerasiri, Nipun Chamikara. 2023. <span>“A Simple Web Server Written in c.”</span> Medium. <a href="https://medium.com/@nipunweerasiri/a-simple-web-server-written-in-c-cf7445002e6">https://medium.com/@nipunweerasiri/a-simple-web-server-written-in-c-cf7445002e6</a>.
</div>
<div id="ref-wikipedia_port" class="csl-entry" role="listitem">
Wikipedia. 2024. <span>“Port (Computer Networking).”</span> Wikipedia. <a href="https://en.wikipedia.org/wiki/Port_(computer_networking)">https://en.wikipedia.org/wiki/Port_(computer_networking)</a>.
</div>
<div id="ref-jeffrey_http" class="csl-entry" role="listitem">
Yu, Jeffrey. 2023. <span>“How i Built a Simple HTTP Server from Scratch Using c.”</span> DEV Community. <a href="https://dev.to/jeffreythecoder/how-i-built-a-simple-http-server-from-scratch-using-c-739">https://dev.to/jeffreythecoder/how-i-built-a-simple-http-server-from-scratch-using-c-739</a>.
</div>
</div>
</section>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr>
<ol>
<li id="fn1"><p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview" class="uri">https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p><a href="https://ziglang.org/documentation/master/std/#std.Io.net.IpAddress.listen" class="uri">https://ziglang.org/documentation/master/std/#std.Io.net.IpAddress.listen</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>It can be also an IPv6 address. But normally, we use a IPv4 address for that.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p><a href="https://en.wikipedia.org/wiki/Media_type" class="uri">https://en.wikipedia.org/wiki/Media_type</a>.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p><a href="https://github.com/oven-sh/bun/blob/main/src/bun.js/webcore/response.zig" class="uri">https://github.com/oven-sh/bun/blob/main/src/bun.js/webcore/response.zig</a>.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>

</main> <!-- /main -->
<script id="quarto-html-after-body" type="application/javascript">
  window.document.addEventListener("DOMContentLoaded", function (event) {
    // Ensure there is a toggle, if there isn't float one in the top right
    if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
      const a = window.document.createElement('a');
      a.classList.add('top-right');
      a.classList.add('quarto-color-scheme-toggle');
      a.href = "";
      a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
      const i = window.document.createElement("i");
      i.classList.add('bi');
      a.appendChild(i);
      window.document.body.appendChild(a);
    }
    setColorSchemeToggle(hasAlternateSentinel())
    const icon = "";
    const anchorJS = new window.AnchorJS();
    anchorJS.options = {
      placement: 'right',
      icon: icon
    };
    anchorJS.add('.anchored');
    const isCodeAnnotation = (el) => {
      for (const clz of el.classList) {
        if (clz.startsWith('code-annotation-')) {                     
          return true;
        }
      }
      return false;
    }
    const onCopySuccess = function(e) {
      // button target
      const button = e.trigger;
      // don't keep focus
      button.blur();
      // flash "checked"
      button.classList.add('code-copy-button-checked');
      var currentTitle = button.getAttribute("title");
      button.setAttribute("title", "Copied!");
      let tooltip;
      if (window.bootstrap) {
        button.setAttribute("data-bs-toggle", "tooltip");
        button.setAttribute("data-bs-placement", "left");
        button.setAttribute("data-bs-title", "Copied!");
        tooltip = new bootstrap.Tooltip(button, 
          { trigger: "manual", 
            customClass: "code-copy-button-tooltip",
            offset: [0, -8]});
        tooltip.show();    
      }
      setTimeout(function() {
        if (tooltip) {
          tooltip.hide();
          button.removeAttribute("data-bs-title");
          button.removeAttribute("data-bs-toggle");
          button.removeAttribute("data-bs-placement");
        }
        button.setAttribute("title", currentTitle);
        button.classList.remove('code-copy-button-checked');
      }, 1000);
      // clear code selection
      e.clearSelection();
    }
    const getTextToCopy = function(trigger) {
        const codeEl = trigger.previousElementSibling.cloneNode(true);
        for (const childEl of codeEl.children) {
          if (isCodeAnnotation(childEl)) {
            childEl.remove();
          }
        }
        return codeEl.innerText;
    }
    const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
      text: getTextToCopy
    });
    clipboard.on('success', onCopySuccess);
    if (window.document.getElementById('quarto-embedded-source-code-modal')) {
      const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
        text: getTextToCopy,
        container: window.document.getElementById('quarto-embedded-source-code-modal')
      });
      clipboardModal.on('success', onCopySuccess);
    }
      var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
      var mailtoRegex = new RegExp(/^mailto:/);
        var filterRegex = new RegExp('/' + window.location.host + '/');
      var isInternal = (href) => {
          return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
      }
      // Inspect non-navigation links and adorn them if external
     var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
      for (var i=0; i<links.length; i++) {
        const link = links[i];
        if (!isInternal(link.href)) {
          // undo the damage that might have been done by quarto-nav.js in the case of
          // links that we want to consider external
          if (link.dataset.originalHref !== undefined) {
            link.href = link.dataset.originalHref;
          }
        }
      }
    function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
      const config = {
        allowHTML: true,
        maxWidth: 500,
        delay: 100,
        arrow: false,
        appendTo: function(el) {
            return el.parentElement;
        },
        interactive: true,
        interactiveBorder: 10,
        theme: 'quarto',
        placement: 'bottom-start',
      };
      if (contentFn) {
        config.content = contentFn;
      }
      if (onTriggerFn) {
        config.onTrigger = onTriggerFn;
      }
      if (onUntriggerFn) {
        config.onUntrigger = onUntriggerFn;
      }
      window.tippy(el, config); 
    }
    const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
    for (var i=0; i<noterefs.length; i++) {
      const ref = noterefs[i];
      tippyHover(ref, function() {
        // use id or data attribute instead here
        let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
        try { href = new URL(href).hash; } catch {}
        const id = href.replace(/^#\/?/, "");
        const note = window.document.getElementById(id);
        if (note) {
          return note.innerHTML;
        } else {
          return "";
        }
      });
    }
    const xrefs = window.document.querySelectorAll('a.quarto-xref');
    const processXRef = (id, note) => {
      // Strip column container classes
      const stripColumnClz = (el) => {
        el.classList.remove("page-full", "page-columns");
        if (el.children) {
          for (const child of el.children) {
            stripColumnClz(child);
          }
        }
      }
      stripColumnClz(note)
      if (id === null || id.startsWith('sec-')) {
        // Special case sections, only their first couple elements
        const container = document.createElement("div");
        if (note.children && note.children.length > 2) {
          container.appendChild(note.children[0].cloneNode(true));
          for (let i = 1; i < note.children.length; i++) {
            const child = note.children[i];
            if (child.tagName === "P" && child.innerText === "") {
              continue;
            } else {
              container.appendChild(child.cloneNode(true));
              break;
            }
          }
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(container);
          }
          return container.innerHTML
        } else {
          if (window.Quarto?.typesetMath) {
            window.Quarto.typesetMath(note);
          }
          return note.innerHTML;
        }
      } else {
        // Remove any anchor links if they are present
        const anchorLink = note.querySelector('a.anchorjs-link');
        if (anchorLink) {
          anchorLink.remove();
        }
        if (window.Quarto?.typesetMath) {
          window.Quarto.typesetMath(note);
        }
        if (note.classList.contains("callout")) {
          return note.outerHTML;
        } else {
          return note.innerHTML;
        }
      }
    }
    for (var i=0; i<xrefs.length; i++) {
      const xref = xrefs[i];
      tippyHover(xref, undefined, function(instance) {
        instance.disable();
        let url = xref.getAttribute('href');
        let hash = undefined; 
        if (url.startsWith('#')) {
          hash = url;
        } else {
          try { hash = new URL(url).hash; } catch {}
        }
        if (hash) {
          const id = hash.replace(/^#\/?/, "");
          const note = window.document.getElementById(id);
          if (note !== null) {
            try {
              const html = processXRef(id, note.cloneNode(true));
              instance.setContent(html);
            } finally {
              instance.enable();
              instance.show();
            }
          } else {
            // See if we can fetch this
            fetch(url.split('#')[0])
            .then(res => res.text())
            .then(html => {
              const parser = new DOMParser();
              const htmlDoc = parser.parseFromString(html, "text/html");
              const note = htmlDoc.getElementById(id);
              if (note !== null) {
                const html = processXRef(id, note);
                instance.setContent(html);
              } 
            }).finally(() => {
              instance.enable();
              instance.show();
            });
          }
        } else {
          // See if we can fetch a full url (with no hash to target)
          // This is a special case and we should probably do some content thinning / targeting
          fetch(url)
          .then(res => res.text())
          .then(html => {
            const parser = new DOMParser();
            const htmlDoc = parser.parseFromString(html, "text/html");
            const note = htmlDoc.querySelector('main.content');
            if (note !== null) {
              // This should only happen for chapter cross references
              // (since there is no id in the URL)
              // remove the first header
              if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
                note.children[0].remove();
              }
              const html = processXRef(null, note);
              instance.setContent(html);
            } 
          }).finally(() => {
            instance.enable();
            instance.show();
          });
        }
      }, function(instance) {
      });
    }
        let selectedAnnoteEl;
        const selectorForAnnotation = ( cell, annotation) => {
          let cellAttr = 'data-code-cell="' + cell + '"';
          let lineAttr = 'data-code-annotation="' +  annotation + '"';
          const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
          return selector;
        }
        const selectCodeLines = (annoteEl) => {
          const doc = window.document;
          const targetCell = annoteEl.getAttribute("data-target-cell");
          const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
          const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
          const lines = annoteSpan.getAttribute("data-code-lines").split(",");
          const lineIds = lines.map((line) => {
            return targetCell + "-" + line;
          })
          let top = null;
          let height = null;
          let parent = null;
          if (lineIds.length > 0) {
              //compute the position of the single el (top and bottom and make a div)
              const el = window.document.getElementById(lineIds[0]);
              top = el.offsetTop;
              height = el.offsetHeight;
              parent = el.parentElement.parentElement;
            if (lineIds.length > 1) {
              const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
              const bottom = lastEl.offsetTop + lastEl.offsetHeight;
              height = bottom - top;
            }
            if (top !== null && height !== null && parent !== null) {
              // cook up a div (if necessary) and position it 
              let div = window.document.getElementById("code-annotation-line-highlight");
              if (div === null) {
                div = window.document.createElement("div");
                div.setAttribute("id", "code-annotation-line-highlight");
                div.style.position = 'absolute';
                parent.appendChild(div);
              }
              div.style.top = top - 2 + "px";
              div.style.height = height + 4 + "px";
              div.style.left = 0;
              let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
              if (gutterDiv === null) {
                gutterDiv = window.document.createElement("div");
                gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
                gutterDiv.style.position = 'absolute';
                const codeCell = window.document.getElementById(targetCell);
                const gutter = codeCell.querySelector('.code-annotation-gutter');
                gutter.appendChild(gutterDiv);
              }
              gutterDiv.style.top = top - 2 + "px";
              gutterDiv.style.height = height + 4 + "px";
            }
            selectedAnnoteEl = annoteEl;
          }
        };
        const unselectCodeLines = () => {
          const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
          elementsIds.forEach((elId) => {
            const div = window.document.getElementById(elId);
            if (div) {
              div.remove();
            }
          });
          selectedAnnoteEl = undefined;
        };
          // Handle positioning of the toggle
      window.addEventListener(
        "resize",
        throttle(() => {
          elRect = undefined;
          if (selectedAnnoteEl) {
            selectCodeLines(selectedAnnoteEl);
          }
        }, 10)
      );
      function throttle(fn, ms) {
      let throttle = false;
      let timer;
        return (...args) => {
          if(!throttle) { // first call gets through
              fn.apply(this, args);
              throttle = true;
          } else { // all the others get throttled
              if(timer) clearTimeout(timer); // cancel #2
              timer = setTimeout(() => {
                fn.apply(this, args);
                timer = throttle = false;
              }, ms);
          }
        };
      }
        // Attach click handler to the DT
        const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
        for (const annoteDlNode of annoteDls) {
          annoteDlNode.addEventListener('click', (event) => {
            const clickedEl = event.target;
            if (clickedEl !== selectedAnnoteEl) {
              unselectCodeLines();
              const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
              if (activeEl) {
                activeEl.classList.remove('code-annotation-active');
              }
              selectCodeLines(clickedEl);
              clickedEl.classList.add('code-annotation-active');
            } else {
              // Unselect the line
              unselectCodeLines();
              clickedEl.classList.remove('code-annotation-active');
            }
          });
        }
    const findCites = (el) => {
      const parentEl = el.parentElement;
      if (parentEl) {
        const cites = parentEl.dataset.cites;
        if (cites) {
          return {
            el,
            cites: cites.split(' ')
          };
        } else {
          return findCites(el.parentElement)
        }
      } else {
        return undefined;
      }
    };
    var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
    for (var i=0; i<bibliorefs.length; i++) {
      const ref = bibliorefs[i];
      const citeInfo = findCites(ref);
      if (citeInfo) {
        tippyHover(citeInfo.el, function() {
          var popup = window.document.createElement('div');
          citeInfo.cites.forEach(function(cite) {
            var citeDiv = window.document.createElement('div');
            citeDiv.classList.add('hanging-indent');
            citeDiv.classList.add('csl-entry');
            var biblioDiv = window.document.getElementById('ref-' + cite);
            if (biblioDiv) {
              citeDiv.innerHTML = biblioDiv.innerHTML;
            }
            popup.appendChild(citeDiv);
          });
          return popup.innerHTML;
        });
      }
    }
  });
  </script>
<nav class="page-navigation">
  <div class="nav-page nav-page-previous">
      <a href="../Chapters/05-pointers.html" class="pagination-link" aria-label="Pointers and Optionals">
        <i class="bi bi-arrow-left-short"></i> <span class="nav-page-text"><span class="chapter-number">6</span>&nbsp; <span class="chapter-title">Pointers and Optionals</span></span>
      </a>          
  </div>
  <div class="nav-page nav-page-next">
      <a href="../Chapters/03-unittests.html" class="pagination-link" aria-label="Unit tests">
        <span class="nav-page-text"><span class="chapter-number">8</span>&nbsp; <span class="chapter-title">Unit tests</span></span> <i class="bi bi-arrow-right-short"></i>
      </a>
  </div>
</nav>
</div> <!-- /content -->




</body></html>